import path from "node:path";
import sharp from "sharp";
import toIco from "to-ico";
import { createInterface } from "node:readline/promises";
import fs from "node:fs/promises";

// 创建readline接口
const readline = createInterface({
  input: process.stdin,
  output: process.stdout
});

// SVG 基础模板
const createIconSVG = (size, maskable = false) => {
  const padding = maskable ? size * 0.1 : 0; // maskable图标需要10%的安全区域
  const centerSize = size - (padding * 2);
  
  return `
    <svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
      <rect width="${size}" height="${size}" fill="${maskable ? '#fff' : 'none'}"/>
      <circle cx="${size/2}" cy="${size/2}" r="${centerSize/2}" fill="#646cff"/>
      <path d="M${size/2 - centerSize/4} ${size/2 - centerSize/4} L${size/2 + centerSize/4} ${size/2} L${size/2 - centerSize/4} ${size/2 + centerSize/4} Z" fill="#fff"/>
    </svg>
  `;
};

// 生成图标配置
const icons = [
  { size: 192, name: "icon-192.png" },
  { size: 512, name: "icon-512.png" },
  { size: 192, name: "icon-192-maskable.png", maskable: true },
  { size: 512, name: "icon-512-maskable.png", maskable: true },
  { size: 32, name: "favicon-32.png" },
  { size: 16, name: "favicon-16.png" },
];

// 支持的文件类型
const SUPPORTED_FORMATS = ['.svg', '.png', '.jpg', '.jpeg'];

// 获取输出目录路径
function getOutputDir() {
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
  const outputDir = path.join(process.cwd(), "output", `icons-${timestamp}`);
  return outputDir;
}

async function ensureDir(dir) {
  try {
    await fs.access(dir);
  } catch {
    await fs.mkdir(dir, { recursive: true });
  }
  return dir;
}

// 检查文件格式是否支持
function isSupportedFormat(filePath) {
  const ext = path.extname(filePath).toLowerCase();
  return SUPPORTED_FORMATS.includes(ext);
}

// 获取文件格式
function getFileFormat(filePath) {
  return path.extname(filePath).toLowerCase().slice(1);
}

// 生成ICO文件的辅助函数
async function generateIco(favicon16Path, favicon32Path, outputPath) {
  try {
    // 读取PNG文件并转换为原始像素数据
    const [img16, img32] = await Promise.all([
      sharp(favicon16Path)
        .ensureAlpha()
        .raw()
        .toBuffer({ resolveWithObject: true }),
      sharp(favicon32Path)
        .ensureAlpha()
        .raw()
        .toBuffer({ resolveWithObject: true })
    ]);

    // 将原始像素数据转回PNG buffer
    const [png16, png32] = await Promise.all([
      sharp(img16.data, {
        raw: {
          width: img16.info.width,
          height: img16.info.height,
          channels: 4
        }
      }).png().toBuffer(),
      sharp(img32.data, {
        raw: {
          width: img32.info.width,
          height: img32.info.height,
          channels: 4
        }
      }).png().toBuffer()
    ]);

    // 生成ICO文件
    const ico = await toIco([png16, png32]);
    await fs.writeFile(outputPath, ico);
    console.log("✓ 已生成 favicon.ico");
  } catch (error) {
    console.error("❌ 生成favicon.ico失败:", error.message);
    throw error;
  }
}

async function generateIcons(inputPath, useTransparentBg = false) {
  console.log("\n🎨 开始生成图标...");
  
  // 创建输出目录
  const outputDir = await ensureDir(getOutputDir());
  console.log(`📁 输出目录: ${outputDir}`);
  
  // 读取输入文件
  const inputFormat = getFileFormat(inputPath);
  const inputBuffer = await fs.readFile(inputPath);
  
  // 生成所有尺寸的PNG图标
  for (const { size, name, maskable } of icons) {
    const padding = maskable ? Math.round(size * 0.1) : 0;
    const image = sharp(inputBuffer);

    // 获取图像元数据
    const metadata = await image.metadata();
    
    // 计算调整大小的参数
    const resizeOptions = {
      width: size - padding * 2,
      height: size - padding * 2,
      fit: 'contain',
      background: useTransparentBg ? { r: 0, g: 0, b: 0, alpha: 0 } : { r: 255, g: 255, b: 255, alpha: 1 }
    };

    // 处理图像
    await image
      .resize(resizeOptions)
      .extend({
        top: padding,
        bottom: padding,
        left: padding,
        right: padding,
        background: maskable ? { r: 255, g: 255, b: 255, alpha: 1 } : 
                  useTransparentBg ? { r: 0, g: 0, b: 0, alpha: 0 } : 
                  { r: 255, g: 255, b: 255, alpha: 1 }
      })
      .png()
      .toFile(path.join(outputDir, name));
    
    console.log(`✓ 已生成 ${name}`);
  }

  // 生成ICO格式的favicon
  try {
    await generateIco(
      path.join(outputDir, "favicon-16.png"),
      path.join(outputDir, "favicon-32.png"),
      path.join(outputDir, "favicon.ico")
    );
  } catch (error) {
    console.error("注意: favicon.ico生成失败，但其他图标已正常生成");
  }

  // 复制原始文件
  const inputFileName = path.basename(inputPath);
  await fs.copyFile(inputPath, path.join(outputDir, inputFileName));
  console.log(`✓ 已复制原始文件: ${inputFileName}`);

  console.log("\n🎯 所有图标生成完成！");
  console.log("\n📝 说明:");
  console.log("- 生成了PWA所需的PNG格式图标");
  console.log("- 生成了ICO格式的favicon（提供最佳兼容性）");
  console.log("- maskable图标包含10%安全区域，适用于自适应图标");
  console.log(`- 所有文件已保存在 ${outputDir} 目录下`);
  if (useTransparentBg) {
    console.log("- 图标使用透明背景（PNG格式）");
  } else {
    console.log("- 图标使用白色背景");
  }
  
  return outputDir;
}

async function main() {
  try {
    console.log("欢迎使用图标生成器！");
    console.log("本工具将帮助你生成PWA应用所需的各种尺寸图标。");
    console.log(`支持的输入格式: ${SUPPORTED_FORMATS.join(', ')}\n`);
    
    const inputPath = await readline.question("请输入图片文件的路径（支持SVG、PNG、JPG格式）: ");
    
    // 检查文件是否存在
    try {
      await fs.access(inputPath);
    } catch {
      throw new Error("找不到指定的文件，请检查路径是否正确。");
    }
    
    // 检查文件格式
    if (!isSupportedFormat(inputPath)) {
      throw new Error(`不支持的文件格式。请使用以下格式之一: ${SUPPORTED_FORMATS.join(', ')}`);
    }

    // 询问是否使用透明背景
    const useTransparent = await readline.question("\n是否使用透明背景？(y/N): ");
    const useTransparentBg = useTransparent.toLowerCase() === 'y';
    
    const outputDir = await generateIcons(inputPath, useTransparentBg);
    
    // 询问是否在文件管理器中打开输出目录
    const openDir = await readline.question("\n是否要在文件管理器中打开输出目录？(y/N): ");
    if (openDir.toLowerCase() === 'y') {
      const command = process.platform === 'win32' ? 'explorer' : 
                     process.platform === 'darwin' ? 'open' : 'xdg-open';
      const { exec } = await import('child_process');
      exec(`${command} "${outputDir}"`);
    }
    
  } catch (error) {
    console.error("\n❌ 错误:", error.message);
  } finally {
    readline.close();
  }
}

main();
